package api

import (
	"errors"
	"image/color"
	"time"

	config2 "github.com/TestsLing/aj-captcha-go/config"
	captchaConst "github.com/TestsLing/aj-captcha-go/const"
	"github.com/TestsLing/aj-captcha-go/service"
	"github.com/gin-gonic/gin"
	"github.com/mojocn/base64Captcha"

	"go-caipu/pkg/api/helper"
	"go-caipu/pkg/constant"
	"go-caipu/pkg/setting"
	"go-caipu/pkg/util"
)

// 基本验证码存储配置
var store = base64Captcha.DefaultMemStore

//swagger:route POST /captcha/captcha getCaptcha 验证码
func (hs *HTTPServer) GetCaptcha(c *gin.Context) {
	driver := base64Captcha.DriverMath{Height: 36, Width: 114}
	code := base64Captcha.NewCaptcha(driver.ConvertFonts(), store)
	id, b64s, _, err := code.Generate()
	if err != nil {
		helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
		return
	}
	helper.SuccessWithData(c, map[string]interface{}{
		"expireTime": time.Now().Add(time.Minute*10).Unix() * 1000,
		"img":        b64s,
		"uuid":       id,
		"isEnabled":  true,
	})
}

// *********************自定义配置**************************************************
// 水印配置（参数可从业务系统自定义）
var watermarkConfig = &config2.WatermarkConfig{
	FontSize: 12,
	Color:    color.RGBA{R: 255, G: 255, B: 255, A: 255},
	Text:     "我的水印",
}

// 点击文字配置（参数可从业务系统自定义）
var clickWordConfig = &config2.ClickWordConfig{
	FontSize: 25,
	FontNum:  4,
}

// 滑动模块配置（参数可从业务系统自定义）
var blockPuzzleConfig = &config2.BlockPuzzleConfig{Offset: 10}

// 行为校验配置模块（具体参数可从业务系统配置文件自定义）
var captchaConfig = config2.BuildConfig(captchaConst.MemCacheKey, captchaConst.DefaultResourceRoot, watermarkConfig,
	clickWordConfig, blockPuzzleConfig, 2*60)

// 行为校验初始化
var factory = service.NewCaptchaServiceFactory(captchaConfig)

// 初始化验证码服务
func ProvideCaptchaService(cfg *setting.Cfg) *service.CaptchaServiceFactory {
	//注册内存缓存
	if cfg.Application.Deploy == "standalone" {
		factory.RegisterCache(captchaConst.MemCacheKey, service.NewMemCacheService(200))
	} else {
		//注册自定义配置redis数据库
		factory.RegisterCache(captchaConst.RedisCacheKey, service.NewConfigRedisCacheService([]string{cfg.RedisConfig.Address},
			cfg.RedisConfig.User, cfg.RedisConfig.Password, false, util.StringToInt(cfg.RedisConfig.Database)))
	}
	factory.RegisterService(captchaConst.ClickWordCaptcha, service.NewClickWordCaptchaService(factory))     //注册点击文字验证码服务
	factory.RegisterService(captchaConst.BlockPuzzleCaptcha, service.NewBlockPuzzleCaptchaService(factory)) //注册滑动模块验证码服务
	return factory
}

type clientParams struct {
	Token       string `json:"token"`
	PointJson   string `json:"pointJson"`
	CaptchaType string `uri:"captchaType"`
}

func (hs *HTTPServer) GetBehaviorCaptcha(c *gin.Context) {
	captchaType := c.Query("captchaType")
	if captchaType == "" {
		helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, errors.New("captchaType 不能为空"))
		return
	}
	result := factory.GetService(captchaType)
	data, err := result.Get()
	if err != nil {
		helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
		return
	}
	helper.SuccessWithData(c, data)
}

//swagger:route POST /captcha/behavior checkBehaviorCaptcha 行为校验
func (hs *HTTPServer) CheckBehaviorCaptcha(c *gin.Context) {
	cmd := clientParams{}
	if err := helper.BindAndValidate(c, &cmd); err != nil {
		return
	}
	result := factory.GetService(cmd.CaptchaType)

	err := result.Check(cmd.Token, cmd.PointJson)
	ret := make(map[string]interface{})
	if err != nil {
		// 校验失败，返回错误信息

		ret["repCode"] = "0001"
		ret["repData"] = err.Error()
		ret["successRes"] = false
		helper.SuccessWithData(c, ret)
		return
	}
	ret["repCode"] = "0000"
	ret["repData"] = "success"
	ret["successRes"] = true
	helper.SuccessWithData(c, ret)
}
